package com.raos.example.func;

import com.raos.example.service.Assistant;
import com.raos.example.util.JsonUtil;
import dev.langchain4j.agent.tool.ToolSpecification;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.request.ChatRequestParameters;
import dev.langchain4j.model.chat.request.json.JsonObjectSchema;
import dev.langchain4j.model.chat.response.ChatResponse;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 函数调用聊天 webAPI（AI智能体入门）
 *
 * @author raos
 * @date 2025-03-27
 */
@Slf4j
@RequestMapping("/api/func")
@RestController
public class FuncAPI {

    @Resource(name = "qwenChatModel")
    ChatLanguageModel languageModel;

    /**
     * 底层API会话
     */
    @GetMapping("/low/chat")
    public String lowChat(@RequestParam(value = "message") String message) {
        log.info("message=[{}]", message);
        ToolSpecification specifications = ToolSpecification.builder()
                .name("Calculator")
                .description("输入两个数，对这两个数求和")
                .parameters(JsonObjectSchema.builder()
                        .addIntegerProperty("a", "第一个参数")
                        .addIntegerProperty("b", "第二个参数")
                        .required("a", "b")
                        .build())
                .build();

        ChatResponse chatResponse = languageModel.doChat(ChatRequest.builder()
                .messages(List.of(UserMessage.from(message)))
                .parameters(ChatRequestParameters.builder().toolSpecifications(specifications).build())
                .build());

        chatResponse.aiMessage().toolExecutionRequests().forEach(toolExecutionRequest -> {
            log.info("调用函数类=[{}]", toolExecutionRequest.name());
            log.info("调用函数使用的参数=[{}]", toolExecutionRequest.arguments());

            try {
                Class<?> aClass = Class.forName("com.raos.example.func." + toolExecutionRequest.name());
                Runnable runnable = (Runnable) JsonUtil.toJsonObject(toolExecutionRequest.arguments(), aClass);
                runnable.run();
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }

        });

        String chat = chatResponse.aiMessage().text();
        log.info("chat=[{}]", chat);
        return chat;
    }

    @Resource(name = "assistant3")
    Assistant assistant;

    /**
     * 高层API会话
     */
    @GetMapping("/high/chat")
    public String highChat(@RequestParam(value = "message") String message) {
        log.info("message=[{}]", message);
        String chat = assistant.chat(message);
        log.info("chat=[{}]", chat);
        return chat;
    }

/*
问答示例
message=[我的两个数字是6和17]
chat=[您想要对这两个数字进行什么操作呢？是要计算它们的和，还是计算它们的差呢？或者有其他的需求？请您详细说明一下。]
message=[计算两数之和，我的两个数字是6和17]
chat=[您提供的两个数字6和17的和是23。]
message=[计算两数之差，我的两个数字是6和17]
chat=[您提供的两个数字6和17的差是-11。这意味着当从6中减去17时，结果是负数，具体为-11。]
*/

}
